﻿using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.WindowsAzure.StorageClient;
using System.ComponentModel.DataAnnotations;
using System.Data.Services.Common;
using LCA.Community.DAL.Model.Extensions;
using System.ComponentModel;

namespace LCA.Community.DAL.Model
{
    /// <summary>
    /// Represents a user of the system.
    /// 
    /// RowKey = Id of the user.
    /// PartitionKey = Username of the user.
    /// </summary>
    public class User : BasicDataModel
    {
        #region Fields
        private IList<Post> posts;
        private IList<Group> groups;
        private IList<User> friends;
        private IList<Message> mailbox;
        private IList<Phrase> greetingsboard;
        private IList<User> volunteers;
        private IList<User> usersHelped;
        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="User"/> class.
        /// </summary>
        public User()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="User"/> class.
        /// </summary>
        /// <param name="liveID">The live ID.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="firstName">The first name.</param>
        /// <param name="lastName">The last name.</param>
        /// <param name="trustworthy">if set to <c>true</c> [trustworthy].</param>
        /// <param name="age">The age.</param>
        /// <param name="city">The city.</param>
        /// <param name="country">The country.</param>
        /// <param name="interests">The interests.</param>
        /// <param name="website">The website.</param>
        /// <param name="email">The email.</param>
        /// <param name="avatar">The avatar.</param>
        /// <param name="hospitalurl">The hospitalurl.</param>
        /// <param name="anonymous">if set to <c>true</c> [anonymous].</param>
        /// <param name="volunteer">if set to <c>true</c> [volunteer].</param>
        public User(string liveID, string userName, string firstName, string lastName, bool trustworthy, int age, string city, string country, string interests, string website, string email, string avatar, string hospitalurl, bool anonymous, bool volunteer)
        {
            RowKey = userName;
            PartitionKey = RowKey;
            FirstName = firstName;
            LastName = lastName;
            Trustworthy = trustworthy;
            Age = age;
            Country = country;
            Interests = interests;
            Website = website;
            Email = email;
            City = city;
            LiveID = liveID;
            Avatar = avatar;
            HospitalUrl = hospitalurl;
            Anonymous = anonymous;
            Volunteer = volunteer;
        }

        /// <summary>
        /// Equalses the specified obj.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns><c>true</c> if both objects are equals; otherwise, <c>false</c>.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            User u = obj as User;
            if ((System.Object)u == null)
            {
                return false;
            }

            return RowKey.Equals(u.RowKey);

        }
        /// <summary>
        /// Gets the hash code.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Gets the short name.
        /// </summary>
        /// <returns>The short name</returns>
        public string GetShortName()
        {
            if (Alias.Length <= 58)
            {
                return RowKey;
            }
            else
            {
                return String.Format("{0}...", RowKey.Substring(0, 58));
            }
        }

        /// <summary>
        /// Gets or sets the row key.
        /// </summary>
        /// <value>
        /// The row key.
        /// </value>
        [Required(ErrorMessage = "Debe introducir un alias.")]
        public override string RowKey { get; set; }
        /// <summary>
        /// Gets or sets the partition key.
        /// </summary>
        /// <value>
        /// The partition key.
        /// </value>
        public override string PartitionKey { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="User"/> is anonimous.
        /// </summary>
        /// <value><c>true</c> if anonimous; otherwise, <c>false</c>.</value>
        [DisplayName("Anónimo")]
        public Boolean Anonymous { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="User"/> is volunteer;
        /// </summary>
        [DisplayName("Voluntario")]
        public bool Volunteer { get; set; }
        /// <summary>
        /// Gets or sets the user's live ID.
        /// </summary>
        /// <value>The user's live ID.</value>
        public String LiveID { get; set; }
        /// <summary>
        /// Gets or sets the first name of the user.
        /// </summary>
        /// <value>The user's first name.</value>
        [Required(ErrorMessage = "Debe introducir su nombre.")]
        [DisplayName("Nombre")]
        public String FirstName { get; set; }
        /// <summary>
        /// Gets or sets the last name of the user.
        /// </summary>
        /// <value>The user's last name.</value>
        [Required(ErrorMessage = "Debe introducir sus apellidos.")]
        [DisplayName("Apellidos")]
        public String LastName { get; set; }
        /// <summary>
        /// The user's age.
        /// </summary>
        [Required(ErrorMessage = "Debe introducir su edad.")]
        [Range(1, 999, ErrorMessage = "Debe introducir su edad correctamente.")]
        [DisplayName("Edad")]
        public int? Age { get; set; }
        /// <summary>
        /// The user's country.
        /// </summary>
        [Required(ErrorMessage = "Debe introducir su país.")]
        [DisplayName("País")]
        public string Country { get; set; }
        /// <summary>
        /// The user's city.
        /// </summary>
        [Required(ErrorMessage = "Debe introducir su ciudad.")]
        [DisplayName("Ciudad")]
        public string City { get; set; }
        /// <summary>
        /// The user's interests.
        /// </summary>
        [DisplayName("Intereses")]
        public string Interests { get; set; }
        /// <summary>
        /// The user's website.
        /// </summary>
        [DisplayName("Página web")]
        public string Website { get; set; }
        /// <summary>
        /// The user's e-mail.
        /// </summary>
        [Required(ErrorMessage = "Debe introducir su email.")]
        [RegularExpression(@"^(([A-Za-z0-9_\+\-]+\.)*[A-Za-z0-9_\+\-]+@([A-Za-z0-9]+\.)+([A-Za-z]{2,4})(\s*(;)\s*))*([A-Za-z0-9_\+\-]+\.)*[A-Za-z0-9_\+\-]+@([A-Za-z0-9]+\.)+([A-Za-z]{2,4})$", ErrorMessage = "El email introducido no es correcto.")]
        [DisplayName("Correo electrónico")]
        public string Email { get; set; }
        /// <summary>
        /// Gets or sets the url of the user's avatar.
        /// </summary>
        /// <value>The user's avatar.</value>
        [DisplayName("Avatar")]
        public string Avatar { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="User"/> is trustworthy.
        /// </summary>
        /// <value><c>true</c> if this user is trustworthy; otherwise, <c>false</c>.</value>
        public bool Trustworthy { get; set; }
        /// <summary>
        /// Gets or sets the hospital URL of the user.
        /// </summary>
        /// <value>The hospital URL of the user.</value>
        [DisplayName("Hospital")]
        public String HospitalUrl { get; set; }
        /// <summary>
        /// Gets or sets the alias of the user.
        /// </summary>
        /// <value>The alias.</value>
        [Required(ErrorMessage = "Debe introducir un alias.")]
        [DisplayName("Alias")]
        public string Alias
        {
            get { return this.RowKey; }
            set { this.RowKey = value; }
        }
        /// <summary>
        /// Gets or sets the ID if the user.
        /// </summary>
        /// <value>The ID.</value>
        public string ID
        {
            get { return this.RowKey; }
            set { }
        }
    }
}
